import Vue from "vue";
import merge from "@/utils/elementUi/utils/merge";
import PopupManager from "@/utils/elementUi/utils/popup/popup-manager";
import getScrollBarWidth from "../scrollbar-width";
import { getStyle, addClass, removeClass, hasClass } from "../dom";

let idSeed = 1;

let scrollBarWidth;

export default {
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    openDelay: {},
    closeDelay: {},
    zIndex: {},
    modal: {
      type: Boolean,
      default: false,
    },
    modalFade: {
      type: Boolean,
      default: true,
    },
    modalClass: {},
    modalAppendToBody: {
      type: Boolean,
      default: false,
    },
    lockScroll: {
      type: Boolean,
      default: true,
    },
    closeOnPressEscape: {
      type: Boolean,
      default: false,
    },
    closeOnClickModal: {
      type: Boolean,
      default: false,
    },
  },

  beforeMount() {
    this._popupId = "popup-" + idSeed++;
    PopupManager.register(this._popupId, this);
  },

  beforeDestroy() {
    PopupManager.deregister(this._popupId);
    PopupManager.closeModal(this._popupId);

    this.restoreBodyStyle();
  },

  data() {
    return {
      opened: false,
      bodyPaddingRight: null,
      computedBodyPaddingRight: 0,
      withoutHiddenClass: true,
      rendered: false,
    };
  },

  watch: {
    visible(val) {
      if (val) {
        if (this._opening) return;
        if (!this.rendered) {
          this.rendered = true;
          Vue.nextTick(() => {
            this.open();
          });
        } else {
          this.open();
        }
      } else {
        this.close();
      }
    },
  },

  methods: {
    open(options) {
      if (!this.rendered) {
        this.rendered = true;
      }

      const props = merge({}, this.$props || this, options);

      if (this._closeTimer) {
        clearTimeout(this._closeTimer);
        this._closeTimer = null;
      }
      clearTimeout(this._openTimer);

      const openDelay = Number(props.openDelay);
      if (openDelay > 0) {
        this._openTimer = setTimeout(() => {
          this._openTimer = null;
          this.doOpen(props);
        }, openDelay);
      } else {
        this.doOpen(props);
      }
    },

    // doOpen(props) {
    //   if (this.$isServer) return;
    //   if (this.willOpen && !this.willOpen()) return;
    //   if (this.opened) return;
    //
    //   this._opening = true;
    //
    //   const dom = this.$el;
    //
    //   const modal = props.modal;
    //
    //   const zIndex = props.zIndex;
    //   if (zIndex) {
    //     PopupManager.zIndex = zIndex;
    //   }
    //
    //   if (modal) {
    //     if (this._closing) {
    //       PopupManager.closeModal(this._popupId);
    //       this._closing = false;
    //     }
    //     PopupManager.openModal(
    //       this._popupId,
    //       PopupManager.nextZIndex(),
    //       this.modalAppendToBody ? undefined : dom,
    //       props.modalClass,
    //       props.modalFade
    //     );
    //     if (props.lockScroll) {
    //       this.withoutHiddenClass = !hasClass(
    //         document.body,
    //         "el-popup-parent--hidden"
    //       );
    //       if (this.withoutHiddenClass) {
    //         this.bodyPaddingRight = document.body.style.paddingRight;
    //         this.computedBodyPaddingRight = parseInt(
    //           getStyle(document.body, "paddingRight"),
    //           10
    //         );
    //       }
    //       scrollBarWidth = getScrollBarWidth();
    //       let bodyHasOverflow =
    //         document.documentElement.clientHeight < document.body.scrollHeight;
    //       let bodyOverflowY = getStyle(document.body, "overflowY");
    //       if (
    //         scrollBarWidth > 0 &&
    //         (bodyHasOverflow || bodyOverflowY === "scroll") &&
    //         this.withoutHiddenClass
    //       ) {
    //         document.body.style.paddingRight =
    //           this.computedBodyPaddingRight + scrollBarWidth + "px";
    //       }
    //       addClass(document.body, "el-popup-parent--hidden");
    //     }
    //   }
    //
    //   if (getComputedStyle(dom).position === "static") {
    //     dom.style.position = "absolute";
    //   }
    //
    //   dom.style.zIndex = PopupManager.nextZIndex();
    //   this.opened = true;
    //
    //   this.onOpen && this.onOpen();
    //
    //   this.doAfterOpen();
    // },
    // 修复上面方法的sonar扫描问题 ---------------start---------------
    doOpen(props) {
      if (this.$isServer) return;
      if (this.willOpen && !this.willOpen()) return;
      if (this.opened) return;

      this._opening = true;

      const dom = this.$el;
      const modal = props.modal;
      const zIndex = props.zIndex;

      this.setZIndex(zIndex);
      this.handleModal(modal, dom, props);
      this.setPosition(dom);
      this.opened = true;
      this.onOpen && this.onOpen();
      this.doAfterOpen();
    },

    setZIndex(zIndex) {
      if (zIndex) {
        PopupManager.zIndex = zIndex;
      }
    },

    handleModal(modal, dom, props) {
      if (modal) {
        this.closeExistingModal();
        this.openNewModal(dom, props);
        this.lockScroll(props.lockScroll);
      }
    },

    closeExistingModal() {
      if (this._closing) {
        PopupManager.closeModal(this._popupId);
        this._closing = false;
      }
    },

    openNewModal(dom, props) {
      PopupManager.openModal(
        this._popupId,
        PopupManager.nextZIndex(),
        this.modalAppendToBody ? undefined : dom,
        props.modalClass,
        props.modalFade
      );
    },

    lockScroll(lockScroll) {
      if (lockScroll) {
        this.withoutHiddenClass = !hasClass(
          document.body,
          "el-popup-parent--hidden"
        );
        if (this.withoutHiddenClass) {
          this.bodyPaddingRight = document.body.style.paddingRight;
          this.computedBodyPaddingRight = parseInt(
            getStyle(document.body, "paddingRight"),
            10
          );
        }
        scrollBarWidth = getScrollBarWidth();
        let bodyHasOverflow =
          document.documentElement.clientHeight < document.body.scrollHeight;
        let bodyOverflowY = getStyle(document.body, "overflowY");
        if (
          scrollBarWidth > 0 &&
          (bodyHasOverflow || bodyOverflowY === "scroll") &&
          this.withoutHiddenClass
        ) {
          document.body.style.paddingRight =
            this.computedBodyPaddingRight + scrollBarWidth + "px";
        }
        addClass(document.body, "el-popup-parent--hidden");
      }
    },

    setPosition(dom) {
      if (getComputedStyle(dom).position === "static") {
        dom.style.position = "absolute";
      }
      dom.style.zIndex = PopupManager.nextZIndex();
    },
    // 修复上面方法的sonar扫描问题 ---------------end---------------

    doAfterOpen() {
      this._opening = false;
    },

    close() {
      if (this.willClose && !this.willClose()) return;

      if (this._openTimer !== null) {
        clearTimeout(this._openTimer);
        this._openTimer = null;
      }
      clearTimeout(this._closeTimer);

      const closeDelay = Number(this.closeDelay);

      if (closeDelay > 0) {
        this._closeTimer = setTimeout(() => {
          this._closeTimer = null;
          this.doClose();
        }, closeDelay);
      } else {
        this.doClose();
      }
    },

    doClose() {
      this._closing = true;

      this.onClose && this.onClose();

      if (this.lockScroll) {
        setTimeout(this.restoreBodyStyle, 200);
      }

      this.opened = false;

      this.doAfterClose();
    },

    doAfterClose() {
      PopupManager.closeModal(this._popupId);
      this._closing = false;
    },

    restoreBodyStyle() {
      if (this.modal && this.withoutHiddenClass) {
        document.body.style.paddingRight = this.bodyPaddingRight;
        removeClass(document.body, "el-popup-parent--hidden");
      }
      this.withoutHiddenClass = true;
    },
  },
};

export { PopupManager };
